package com.wisdudu.blank.data.source.remote;

import android.util.Log;

import com.wisdudu.blank.data.Injection;
import com.wisdudu.blank.data.bean.CityInfo;
import com.wisdudu.blank.data.bean.ImageLoad;
import com.wisdudu.blank.data.bean.PersonalInfo;
import com.wisdudu.blank.data.bean.SystemImg;
import com.wisdudu.blank.data.bean.UserInfo;
import com.wisdudu.blank.data.bean.VersionInfo;
import com.wisdudu.blank.data.repo.UserDataSource;
import com.wisdudu.blank.data.source.remote.client.retrofit.subscribers.Abs;
import com.wisdudu.blank.data.source.remote.client.retrofit.subscribers.ListPoint;
import com.wisdudu.blank.data.source.remote.client.retrofit.subscribers.MapSort;
import com.wisdudu.blank.data.source.remote.client.retrofit.subscribers.ProgressSubscriber;
import com.wisdudu.blank.data.source.remote.client.retrofit.subscribers.func.AbsFunc;
import com.wisdudu.blank.data.source.remote.service.LoadService;
import com.wisdudu.blank.data.source.remote.service.SzService;
import com.wisdudu.frame.support.util.MD5Util;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

import static android.content.ContentValues.TAG;

/**
 * Created by qyf on 2016/8/17.
 */

public class UserRemoteDataSource implements UserDataSource {
    private static UserRemoteDataSource INSTANCE;

    private UserRemoteDataSource() {
    }

    public static UserRemoteDataSource getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new UserRemoteDataSource();
        }
        return INSTANCE;
    }

    @Override
    public void getUserList() {

    }

    /**
     * 图片上传接口
     *
     * @param path 文件路径
     * @return 可空, 完整组装imageurl, 可直接用Glide加载
     * !!!注意切换线程
     */
    public Observable<String> uploadFile(String path) {
        return Observable.just(path).flatMap(new Func1<String, Observable<String>>() {
            @Override
            public Observable<String> call(String path) {
                if (path.startsWith("http://")) {
                    return Observable.just(path);
                }
                return uploadFile(new File(path), "file");
            }
        });

    }

    /**
     * 上传多个文件,返回顺序与传入顺序一致
     * 不用担心顺序问题
     *
     * @param paths 图片路径集合
     * @return 图片完整路径urls
     */
    public Observable<List<String>> uploadFile(List<String> paths) {
        return uploadFile(paths, "file").subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 上传多个文件
     *
     * @param paths 图片路径集合
     * @return 图片完整路径urls
     */
    private Observable<List<String>> uploadFile(List<String> paths, String type) {
        return Observable.from(paths).concatMap(s -> {
            if (s.startsWith("http://")) {
                return Observable.just(s);
            } else {
                return uploadFile(new File(s), type);
            }
        }).toList();
//        List<MultipartBody.Part> parts = new ArrayList<>();
//        for (String path : paths) {
//            File file = new File(path);
//            RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
////        // MultipartBody.Part is used to send also the actual file name
//            String[] split = file.getName().split("/");
////            String str = type + ";filename=" + split[split.length - 1];
//            MultipartBody.Part body =
//                    MultipartBody.Part.createFormData(type, split[split.length - 1], requestFile);
//            parts.add(body);
//        }
//        return ServiceClient.getLoadService().upload(parts).observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()).map(new Func1<Response<ResponseBody>, List<String>>() {
//            @Override
//            public List<String> call(Response<ResponseBody> responseBodyCall) {
//                try {
//                    String string = responseBodyCall.body().string();
//                    JSONObject jsonObject = new JSONObject(string);
//                    String urlStr = jsonObject.getString("url").trim();
//                    if (TextUtils.isEmpty(urlStr)) {
//                        return null;
//                    }
//                    String[] urls = urlStr.split(",");
//                    String[] filenames = jsonObject.getString("filename").trim().split(",");
//                    List<String> paths = new ArrayList<>();
//                    for (int i = 0; i < urls.length; i++) {
//                        paths.add(API.baseLoadFileUrl + urls[i].substring(1) + "/" + filenames[i]);
//                    }
//                    return paths;
//                } catch (Exception e) {
//                    e.printStackTrace();
//                    return null;
//                }
//
//            }
//        });

    }

    /**
     * 上传不同文件类型
     *
     * @param file 文件
     * @param type 类型，有 file,image,flash,media四种
     * @return 返回文件地址, 可空
     */
    public Observable<String> uploadFile(File file, String type) {
        Log.i(TAG, "uploadFile:路径 " + file.getAbsolutePath());
//        RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), file);
//        Call<ResponseBody> call = ServiceClient.getLoadService().upload(description);
        // create RequestBody instance from file
        RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
//        // MultipartBody.Part is used to send also the actual file name
        String[] split = file.getName().split("/");
        MultipartBody.Part body = MultipartBody.Part.createFormData(type, split[split.length - 1], requestFile);

        return LoadService.INSTANCE.getApi().upload(body)
                .map(new AbsFunc<>())
                .map(ImageLoad::getSrc);
    }

    /**
     * role 物业3 商家2 其他0
     *
     * @param phoneNum
     * @param password
     * @return
     */
    public Observable<UserInfo> login(String phoneNum, String password) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("phone", phoneNum);
        map.put("pwds", MD5Util.getMD5Login(password));
        map.put("role", 0);
        return SzService.INSTANCE.getApi().login(MapSort.getLoginMD5PostMap(map))
                .map(new AbsFunc<>())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io());
    }


    /**
     * 注册
     *
     * @param phone
     * @param password
     * @param code     验证码
     * @return
     */
    public void register(ProgressSubscriber<UserInfo> registSubscriber, String phone, String password, String code) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("phone", phone);
        map.put("password", password);
        map.put("code", code);
        map.put("role", 1);

        SzService.INSTANCE.getApi().registerUser(MapSort.getMD5PostResultMap(map))
                .map(new AbsFunc())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .subscribe(registSubscriber);

    }

    /**
     * 发送短信
     *
     * @param phone
     * @param type  1:注册 2：找回密码
     * @return
     */
    public Observable<Object> getSmsCode(String phone, int type) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("phone", phone);
        map.put("type", type);
        return SzService.INSTANCE.getApi().getSmsCode(MapSort.getMD5PostResultMap(map))
                .map(new AbsFunc<Object>())
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 完善个人资料-昵称
     *
     * @param uid
     * @param nick
     * @param sex  用户性别 1：男 2：女
     * @param type
     * @return
     */
    public Observable<Object> editUserNick(int uid, String nick, int sex, int type) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("uid", uid);
        map.put("nick", nick);
        map.put("sex", sex);
        map.put("type", type);
        return SzService.INSTANCE.getApi().editUserNick(MapSort.getMD5PostResultMap(map))
                .map(new AbsFunc<Object>())
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 重置密码
     *
     * @param phone
     * @param code
     * @param pwds
     * @return
     */
    public void resetPwd(ProgressSubscriber<Abs> subscriber, String phone, String code, String pwds) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("phone", phone);
        map.put("pwds", pwds);
        map.put("code", code);
        SzService.INSTANCE.getApi().resetPwd(MapSort.getMD5PostResultMap(map))
                .map(new AbsFunc())
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }

    /**
     * 按用户属性键修改用户信息接口
     *
     * @param key   用户属性字段[字段说明
     *              nickname：用户昵称
     *              faces：用户头像
     *              qq：QQ联系方式
     *              sex：性别
     *              autograph：自我描述
     *              houseNumber：默认门牌号
     *              background：用户背景图片]
     * @param value
     */
    public Observable<Object> editUserInfo(int userId, String key, String value) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("userid", userId);
        map.put("key", key);
        map.put("val", value);
        return SzService.INSTANCE.getApi().editUserInfo(MapSort.getMD5PostResultMap(map))
                .map(new AbsFunc<>())
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 获取系统图片
     */
    public Observable<List<SystemImg>> getSystemImg() {
        HashMap<String, Object> map = new HashMap<>();
        return SzService.INSTANCE.getApi().getSystemImg(MapSort.getMD5PostResultMap(map))
                .map(new AbsFunc<>())
                .map(ListPoint::getList)
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 获取个人信息
     */
    public Observable<PersonalInfo> getUserInfo(int userId) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("userid", userId);
        return SzService.INSTANCE.getApi().getUserInfo(MapSort.getMD5PostResultMap(map))
                .map(new AbsFunc<>())
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 版本更新
     * 1：B版APP [默认]
     * 2：商家版APP
     * 3：物业版APP
     *
     * @return
     */
    public Observable<VersionInfo> getVersion() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("type", 4);
        return SzService.INSTANCE.getApi().getVersion(MapSort.getMD5GetResult(map))
                .map(new AbsFunc<>())
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 修改密码
     *
     * @param uid
     * @param password
     * @param reNewPassword
     * @return
     */
    public Observable<Object> editPass(String uid, String password, String reNewPassword) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("uid", uid);
        map.put("oldpwds", password);
        map.put("newpwds", reNewPassword);
        return SzService.INSTANCE.getApi().editPass(MapSort.getMD5GetResult(map))
                .map(new AbsFunc())
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 意见反馈
     *
     * @param uid
     * @param content
     * @return
     */
    public Observable<Abs> feedback(String uid, String content) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("userid", uid);
        map.put("content", content);
        return SzService.INSTANCE.getApi().feedback(MapSort.getMD5PostResultMap(map)).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }



    /**
     * 获取城市列表
     *
     * @param provinceid 省份ID，获取省份时，传递值 1
     * @param region     等级 1：省份 2：城市 3：地区
     * @param type       1：配送地址使用 2：注册使用
     * @return
     */
    public Observable<List<CityInfo>> getCity(int provinceid, int region, int type) {
        Map<String, Object> map = new HashMap<>();
        map.put("provinceid", provinceid);
        map.put("region", region);
        map.put("type", type);
        return SzService.INSTANCE.getApi().getCity(MapSort.getMD5PostResultMap(map))
                .map(new AbsFunc<>())
                .map(listListPoint -> listListPoint.getList())
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    // 用户切换小区接口
    // role 物业3 商家2 其他0
    public Observable<UserInfo> setVillage(int villageid) {
        Map<String, Object> map = new HashMap<>();
        map.put("userid", Injection.provideUserRepo().getUid());
        map.put("villageid", villageid);
        map.put("role", 0);

        return SzService.INSTANCE.getApi().setVillage(MapSort.getMD5PostResultMap(map))
                .map(new AbsFunc<>()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

}
